<template>
  <view class="container">
    <!-- 导航栏 -->
    <uni-nav-bar 
      dark 
      :fixed="true" 
      shadow 
      status-bar 
      left-icon="arrow-left" 
      right-icon="refreshempty" 
      title="走访登记" 
      @clickLeft="back" 
      @clickRight="refreshData"
      height="56"
      :left-icon-size="28" 
      :right-icon-size="28"
      custom-style="background-color: #0056D2; font-weight: 600; font-size: 19px;" 
    />
    
    <!-- 主内容区 -->
    <view class="main-content">
      <!-- 搜索区域 -->
      <view class="search-container">
        <view class="search-box">
          <uni-icons type="search" size="18" color="#999" class="search-icon"></uni-icons>
          <input 
            type="text" 
            v-model="searchKeyword" 
            placeholder="请输入客户名称搜索"
            class="search-input"
            @confirm="searchData"
          />
        </view>
        
        <view class="filter-row">
          <view class="filter-item">
            <uni-datetime-picker 
              v-model="dateRange" 
              type="daterange" 
              range-separator="~" 
              :clear-icon="false"
              :start-placeholder="dateRange[0]"
              :end-placeholder="dateRange[1]"
              @change="handleDateChange"
              class="date-picker"
            />
          </view>
        </view>
      </view>

      <!-- 滚动容器 -->
      <scroll-view 
        class="card-scroll-container"
        scroll-y="true"
        :style="{ height: tableHeight }"
        @scrolltolower="handleLoadMore"
      >
        <view class="card-list">
          <!-- 空数据状态 -->
          <view class="float-state-layer" v-if="(filteredTableData.length === 0 && !isLoadingMore) || loading">
            <view class="state-content">
              <view class="state-inner" v-if="loading">
                <uni-icons type="spinner" size="30" color="#007aff" class="loading-spin"></uni-icons>
                <text class="state-text">加载中...</text>
              </view>
              
              <view class="state-inner" v-else>
                <uni-icons type="empty" size="60" color="#ccc"></uni-icons>
                <text class="state-text">暂无客户数据</text>
                <button class="add-btn" @click="navigateToAdd">
                  <uni-icons type="plus" size="18" color="#007aff"></uni-icons>
                  立即新增
                </button>
              </view>
            </view>
          </view>

          <!-- 卡片列表 -->
          <view 
            class="data-card" 
            v-for="(item, index) in filteredTableData" 
            :key="`data-${index}-${item?.id || item?.khCode || Date.now() + index}`"  
            :class="index % 2 === 0 ? 'card-even' : 'card-odd'"
          >
            <!-- 卡片头部：客户名称 -->
            <view class="card-header">
              <view class="customer-name">
                <text class="label">客户名称：</text>
                <text class="value">{{ getCustomerName(item) }}</text>
              </view>
            </view>
            
            <!-- 卡片主体：走访详情 + 操作区 -->
            <view class="card-body">
              <!-- 详情区域 -->
              <view class="detail-group">
                <view class="detail-item">
                  <text class="detail-label">走访方式：</text>
                  <text class="detail-value">{{ item?.tCwqfZffs?.name || '未设置' }}</text>
                </view>
                <view class="detail-item">
                  <text class="detail-label">联系电话：</text>
                  <text class="detail-value">{{ item?.lxdh || item?.tbCrmCustomer?.contactTel || '未填写' }}</text>
                </view>
                <view class="detail-item">
                  <text class="detail-label">备注信息：</text>
                  <text class="detail-value">{{ item?.bz || '未填写' }}</text>
                </view>
                <!-- 附件展示区域 -->
                <view v-if="item.wjids && item.wjids.length" class="detail-item">
                  <text class="detail-label">附件：</text>
                  <view class="attachment-list">
                    <view 
                      class="attachment-item" 
                      v-for="(wjId, idx) in item.wjids" 
                      :key="`attach-${idx}-${wjId}`"
                      @click="previewAttachment(wjId)"
                    >
                      <uni-icons type="image" size="16" color="#007aff" class="attach-icon"></uni-icons>
                      <text class="attach-name">附件{{ idx + 1 }}</text>
                    </view>
                  </view>
                </view>
                <view class="detail-item">
                  <text class="detail-label">录入日期：</text>
                  <text class="detail-value">{{ formatDate(item?.lrrq) || '未记录' }}</text>
                </view>
              </view>
              
              <!-- 操作区 -->
              <view class="card-actions">
                <button 
                  class="delete-btn" 
                  @click="confirmDelete(item)"
                  :disabled="deleteLoading[item.id || item.khCode]"
                >
                  <uni-icons 
                    type="spinner" 
                    size="14" 
                    color="#fff" 
                    class="loading-spin"
                    v-if="deleteLoading[item.id || item.khCode]"
                  ></uni-icons>
                  <uni-icons 
                    type="trash" 
                    size="14" 
                    color="#fff" 
                    v-else
                  ></uni-icons>
                  <text>{{ deleteLoading[item.id || item.khCode] ? '删除中...' : '删除' }}</text>
                </button>
              </view>
            </view>
          </view>
          
          <!-- 加载提示 -->
          <view v-if="isLoadingMore" class="loading-tip">
            <uni-icons type="spinner" size="24" color="#007aff" class="loading-spin"></uni-icons>
            <text class="loading-text">加载中...</text>
          </view>
          
          <!-- 无更多数据提示 -->
          <view v-if="showNoMoreTip && !hideNoMoreTip" class="loading-tip" :class="{fadeOut: startFadeOut}">
            <text>已显示全部数据</text>
          </view>
        </view>
      </scroll-view>
      
      <!-- 分页信息 #007aff-->
      <view class="pagination-info">
        <text>第 <text style="color: red; font-weight: bold;">{{ currentPage }}</text> 页 / 共 <text style="color: red; font-weight: bold;">{{ totalPages || 0 }}</text> 页</text>
        <text style="margin: 0 8px; color: #ccc;">|</text>
        <text>已展示 <text style="color: red; font-weight: bold;">{{ tableData.length }}</text> 条 / 共 <text style="color: red; font-weight: bold;">{{ totalCount || 0 }}</text> 条</text>
      </view>
      
      <!-- 悬浮新增按钮 -->
      <button class="add-btn-float" @click="navigateToAdd">
        <uni-icons type="plus" size="24" color="#fff"></uni-icons>
      </button>
    </view>
  </view>
</template>

<script>
import utils from '../../common/utils'

export default {
  data() {
    return {
      tableData: [],
      currentPage: 1,
      pageSize: 30,
      totalCount: 0,
      totalPages: 0,
      sortConfig: { key: '', type: 'asc' },
      searchKeyword: '',
      dateRange: [],
      loading: false,
      isLoadingMore: false,
      hasMoreData: true,
      tableHeight: '600px',
      hideNoMoreTip: false,
      startFadeOut: false,
      noMoreTimer: null,
      deleteLoading: {}
    };
  },
  computed: {
    filteredTableData() {
      let data = Array.isArray(this.tableData) ? [...this.tableData] : [];
      data = data.filter(item => item && typeof item === 'object');
      
      if (this.searchKeyword) {
        const keyword = this.searchKeyword.toLowerCase();
        data = data.filter(item => {
          const name = this.getCustomerName(item).toLowerCase();
          return name.includes(keyword);
        });
      }
      
      if (this.sortConfig.key) {
        data.sort((a, b) => this.sortCompare(a, b));
      }
      
      return data;
    },
    showNoMoreTip() {
      return !this.hasMoreData && this.totalCount > 0 && !this.isLoadingMore && this.tableData.length >= this.pageSize;
    }
  },
  watch: {
    showNoMoreTip(newVal) {
      if (this.noMoreTimer) {
        clearTimeout(this.noMoreTimer);
        this.noMoreTimer = null;
      }
      
      if (newVal) {
        this.hideNoMoreTip = false;
        this.startFadeOut = false;
        
        this.noMoreTimer = setTimeout(() => {
          this.startFadeOut = true;
          setTimeout(() => {
            this.hideNoMoreTip = true;
          }, 500);
        }, 1500);
      } else {
        this.hideNoMoreTip = true;
        this.startFadeOut = false;
      }
    }
  },
  onLoad() {
    this.calculateTableLayout();
    this.getDefaultDateRange();
    this.initPage(this.currentPage);
    uni.onWindowResize(this.calculateTableLayout);
  },
  onUnload() {
    uni.offWindowResize(this.calculateTableLayout);
    if (this.noMoreTimer) clearTimeout(this.noMoreTimer);
  },
  methods: {
    calculateTableLayout() {
      try {
        const { windowHeight, statusBarHeight } = uni.getSystemInfoSync();
        const navHeight = 56;
        const searchHeight = 140;
        const paginationHeight = 40;
        this.tableHeight = `${windowHeight - navHeight - searchHeight - paginationHeight - statusBarHeight}px`;
      } catch (e) {
        console.error('计算布局失败:', e);
        this.tableHeight = '500px';
      }
    },
    
    handleLoadMore() {
      if (this.isLoadingMore || !this.hasMoreData) return;
      if (this.currentPage >= this.totalPages) {
        this.hasMoreData = false;
        return;
      }
      
      this.isLoadingMore = true;
      this.currentPage += 1;
      
      this.initPage(this.currentPage).then(() => {
        this.isLoadingMore = false;
        this.hasMoreData = this.currentPage < this.totalPages;
      }).catch(() => {
        this.currentPage -= 1;
        this.isLoadingMore = false;
        uni.showToast({ title: '加载更多失败', icon: 'none' });
      });
    },
    
    refreshData() {
      this.currentPage = 1;
      this.tableData = [];
      this.hasMoreData = true;
      this.hideNoMoreTip = true;
      this.startFadeOut = false;
      this.initPage(this.currentPage);
    },
    
    getDefaultDateRange() {
      const today = new Date();
      const threeMonthsAgo = new Date();
      threeMonthsAgo.setMonth(today.getMonth() - 3);
      
      if (threeMonthsAgo.getDate() !== today.getDate()) {
        threeMonthsAgo.setDate(0);
      }
      
      const format = (date) => {
        return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
      };
      
      this.dateRange = [format(threeMonthsAgo), format(today)];
    },
    
    handleDateChange(newRange) {
      this.dateRange = newRange;
      this.searchData();
    },
    
    initPage: async function(pageNum) {
      if (pageNum === 1) this.loading = true;
      
      try {
        const userInfo = uni.getStorageSync("userInfo");
        if (!userInfo?.aesKey || !userInfo?.aesIv) {
          uni.showToast({ title: '请先登录', icon: 'none' });
          return Promise.reject(new Error('未登录'));
        }
        
        const requestData = {
          timestamp: Date.now(),
          curpage: pageNum,
          pagesize: this.pageSize,
          keyword: this.searchKeyword,
          ksrq: this.dateRange[0],
          jsrq: this.dateRange[1]
        };
        
        const encryptedData = this.$utils.encrypt(
          JSON.stringify(requestData),
          userInfo.aesKey,
          userInfo.aesIv
        );
        
        const res = await this.$myRequest.post_token(
          getApp().globalData.khzf + "/query",
          { data: encryptedData }
        );
        
        if (pageNum === 1) this.loading = false;
        
        if (res.code === 200 && res.data) {
          const decrypted = utils.decrypt(res.data, userInfo.aesKey, userInfo.aesIv);
          const result = JSON.parse(decrypted);
          
          const newData = Array.isArray(result.listInfo) 
            ? result.listInfo 
            : Array.isArray(result.dataList) 
              ? result.dataList 
              : Array.isArray(result) 
                ? result 
                : [];
          
          this.tableData = pageNum === 1 ? newData : [...this.tableData, ...newData];
          this.totalCount = result.pageInfo?.total || result.totalCount || 0;
          this.totalPages = result.pageInfo?.pageTotal || Math.ceil(this.totalCount / this.pageSize) || 0;
          this.hasMoreData = pageNum < this.totalPages;
          
          return Promise.resolve();
        } else {
          uni.showToast({ title: `加载失败！错误码[${res.code}]`, icon: 'none' });
          return Promise.reject(new Error(`接口错误: ${res.code}`));
        }
      } catch (e) {
        if (pageNum === 1) this.loading = false;
        console.error('加载异常：', e);
        uni.showToast({ title: '网络错误，加载失败', icon: 'none' });
        return Promise.reject(e);
      }
    },
    
    searchData() {
      this.currentPage = 1;
      this.tableData = [];
      this.hasMoreData = true;
      this.hideNoMoreTip = true;
      this.initPage(this.currentPage);
    },
    
    sortCompare(a, b) {
      let valA, valB;
      
      switch (this.sortConfig.key) {
        case 'partyName':
          valA = this.getCustomerName(a);
          valB = this.getCustomerName(b);
          break;
        case 'visitType':
          valA = a.tCwqfZffs?.name || '';
          valB = b.tCwqfZffs?.name || '';
          break;
        case 'contactPhone':
          valA = a.lxdh || a.tbCrmCustomer?.contactTel || '';
          valB = b.lxdh || b.tbCrmCustomer?.contactTel || '';
          break;
        case 'inputDate':
          valA = new Date(a.lrrq || 0).getTime();
          valB = new Date(b.lrrq || 0).getTime();
          return this.sortConfig.type === 'asc' ? valA - valB : valB - valA;
        default:
          return 0;
      }
      
      const compare = valA.localeCompare(valB, 'zh-CN');
      return this.sortConfig.type === 'asc' ? compare : -compare;
    },
    
    getCustomerName(item) {
      if (!item) return '未知客户';
      return item.tbCrmCustomer?.partyName 
        || item.tbCrmCustomer?.customerName 
        || item.khName 
        || item.name 
        || '未命名';
    },
    
    formatDate(timestamp) {
      if (!timestamp) return '';
      try {
        const date = new Date(
          typeof timestamp === 'string' && timestamp.length === 10 
            ? parseInt(timestamp) * 1000 
            : timestamp
        );
        return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
      } catch (e) {
        return timestamp.toString();
      }
    },
    
    handleSort(key) {
      if (this.sortConfig.key === key) {
        this.sortConfig.type = this.sortConfig.type === 'asc' ? 'desc' : 'asc';
      } else {
        this.sortConfig = { key, type: 'asc' };
      }
    },
    
    back() {
      uni.switchTab({
        url: '/pages/index/index',
        fail: (err) => {
          uni.redirectTo({
            url: '/pages/index/index',
            fail: (err2) => {
              console.error('跳转index页面失败：', err2);
              uni.navigateBack();
            }
          });
        }
      });
    },
    
    navigateToAdd() {
      uni.navigateTo({ url: '/pages/khzf/info' });
    },
    
    confirmDelete: async function(item) {
      const itemId = item.id || item.khCode;
      if (!itemId) {
        uni.showToast({ title: '参数缺失，无法删除', icon: 'none' });
        return;
      }
      
      if (this.deleteLoading[itemId]) return;
      
      // 替换你原来的uni.showModal调用部分
      uni.showModal({
        title: '确认删除',
        content: `确定要删除【${this.getCustomerName(item)}】的走访记录吗？`,
        confirmText: '取消', // 右侧按钮显示“取消”
        cancelText: '确认删除', // 左侧按钮显示“确认删除”
        confirmColor: '#666', // 取消按钮用默认灰色
        cancelColor: '#165DFF', // 确认删除按钮高亮蓝色
        success: async (res) => {
          // 核心：点击左侧“确认删除”按钮（对应res.cancel为true）
          if (res.cancel) { 
            try {
              // 显示加载状态
              this.$set(this.deleteLoading, itemId, true);
              
              // 验证登录状态
              const userInfo = uni.getStorageSync("userInfo");
              if (!userInfo?.aesKey || !userInfo?.aesIv) {
                uni.showToast({ title: '请先登录', icon: 'none' });
                throw new Error('未登录');
              }
              
              // 构建删除参数并加密
              const deleteParams = {
                timestamp: Date.now(),
                id: itemId
              };
              const encryptedData = this.$utils.encrypt(
                JSON.stringify(deleteParams),
                userInfo.aesKey,
                userInfo.aesIv
              );
              
              // 调用删除接口
              const res = await this.$myRequest.post_token(
                getApp().globalData.khzf + "/del",
                { data: encryptedData }
              );
              
              // 处理接口返回
              if (res.code === 200) {
                uni.showToast({ title: '删除成功', icon: 'success', duration: 1500 });
                this.refreshData(); // 刷新列表数据
              } else {
                throw new Error(`删除失败！错误码[${res.code}]`);
              }
            } catch (error) {
              // 错误处理
              console.error('删除异常：', error);
              uni.showToast({ 
                title: error.message || '网络错误，删除失败', 
                icon: 'none',
                duration: 2000
              });
            } finally {
              // 无论成功失败，关闭加载状态
              this.$set(this.deleteLoading, itemId, false);
            }
          }
          // 点击右侧“取消”按钮（res.confirm为true），不做任何操作
        }
      });
    },
    
	previewAttachment(wjId) {
	  if (!wjId) return;
	  // 获取token
	  const token = uni.getStorageSync("userInfo")?.token || "";
	  // 构造新的图片URL
	  const imageUrl = `http://stjk.whsyzj.com/cwqf-api/qyh/khzf/fj?id=${wjId}&token=${token}`;
	  uni.previewImage({
		urls: [imageUrl],
		current: imageUrl,
		fail: (err) => {
		  console.error('图片预览失败：', err);
		  uni.showToast({ title: '图片加载失败', icon: 'none' });
		}
	  });
	}
  }
};
</script>

<style scoped>
.container {
  width: 100%;
  height: 100vh;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: #f5f5f5;
}

.main-content {
  flex: 1;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-top: 0;
}

.search-container {
  background-color: #fff;
  padding: 15rpx 20rpx;
  margin-bottom: 10rpx;
  box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.05);
}

.search-box {
  display: flex;
  align-items: center;
  background-color: #f2f2f2;
  border-radius: 60rpx;
  padding: 10rpx 20rpx;
  margin-bottom: 15rpx;
}

.search-icon {
  margin-right: 10rpx;
}

.search-input {
  flex: 1;
  height: 60rpx;
  font-size: 28rpx;
  color: #333;
  background-color: transparent;
  border: none;
  outline: none;
}

.filter-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 15rpx;
}

.filter-item {
  display: flex;
  align-items: center;
  width: 100%;
  min-width: 280rpx;
}

.date-picker {
  width: 100%;
  min-width: 300rpx;
}

.card-scroll-container {
  width: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background-color: #f5f5f5;
  padding: 0 10px;
  box-sizing: border-box;
  flex: 1;
}

.card-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
  padding: 15px 0 30px;
}

.data-card {
  background-color: #fff;
  border-radius: 16px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  transition: all 0.3s ease;
  border: none;
}

.data-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}

.card-even {
  border-left: 4px solid #007aff;
}

.card-odd {
  border-left: 4px solid #ff4d4f;
}

.card-header {
  padding: 18px 22px;
  border-bottom: 1px solid #f5f5f5;
  background-color: #fafafa;
}

.customer-name {
  display: flex;
  align-items: center;
  font-size: 16px;
}

.label {
  color: #666;
  margin-right: 8px;
  font-weight: 400;
}

.value {
  color: #222;
  font-weight: 600;
  word-break: break-all;
}

.card-body {
  padding: 20px 22px 15px;
}

.detail-group {
  margin-bottom: 12px;
}

.detail-item {
  display: flex;
  align-items: center;
  font-size: 15px;
  margin-bottom: 10px;
  line-height: 1.5;
}

.detail-label {
  color: #666;
  margin-right: 8px;
  white-space: nowrap;
  width: 80px;
}

.detail-value {
  color: #333;
  font-weight: 500;
  flex: 1;
}

/* 附件样式 */
.attachment-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10rpx;
  margin-top: 5rpx;
}

.attachment-item {
  display: flex;
  align-items: center;
  gap: 4rpx;
  padding: 6rpx 12rpx;
  background-color: #f0f7ff;
  border: 1px solid #e1efff;
  border-radius: 6rpx;
  color: #007aff;
  font-size: 14px;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.attachment-item:hover {
  background-color: #e1efff;
}

.attach-icon {
  margin-top: 1rpx;
}

.card-actions {
  width: 100%;
  overflow: hidden;
  padding-top: 8px;
  border-top: 1px dashed #eee;
}

.delete-btn {
  float: right;
  display: flex;
  align-items: center;
  gap: 5px;
  background-color: #ff4d4f;
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 5px 12px;
  font-size: 12px;
  height: 30px;
  line-height: 1;
  transition: all 0.2s ease;
}

.delete-btn:disabled {
  background-color: #ff8a80;
  cursor: not-allowed;
}

.delete-btn:hover:not(:disabled) {
  background-color: #ff3a30;
  box-shadow: 0 2px 6px rgba(255, 77, 79, 0.25);
}

.float-state-layer {
  position: static;
  padding: 60px 0;
  background-color: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
}

.state-content {
  width: 100%;
  max-width: 400px;
  padding: 20px;
  box-sizing: border-box;
}

.state-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.state-text {
  font-size: 28rpx;
  color: #999;
  margin-top: 20rpx;
  text-align: center;
}

.state-inner .add-btn {
  margin-top: 30rpx;
  background-color: transparent;
  color: #007aff;
  font-size: 28rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8rpx;
  border: none;
}

.loading-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 15px 0;
  color: #666;
  font-size: 14px;
  text-align: center;
  width: 100%;
  box-sizing: border-box;
  transition: opacity 0.5s ease;
}

.loading-tip.fadeOut {
  opacity: 0;
}

.loading-text {
  margin-left: 8px;
}

.pagination-info {
  height: 40px;
  line-height: 40px;
  font-size: 13px;
  color: #666;
  text-align: center;
  border-top: 1px solid #eee;
  background-color: #f9f9f9;
  position: relative;
  z-index: 20;
  width: 100%;
  box-sizing: border-box;
  margin-top: auto;
}

.add-btn-float {
  position: fixed;
  bottom: 100rpx;
  right: 30rpx;
  background-color: #007aff;
  color: #fff;
  width: 120rpx;
  height: 120rpx;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4rpx 15rpx rgba(0, 122, 255, 0.4);
  z-index: 99;
  border: none;
}

.loading-spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.card-scroll-container::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.card-scroll-container::-webkit-scrollbar-thumb {
  background-color: #ddd;
  border-radius: 3px;
}

@media (max-width: 375px) {
  .card-body {
    padding: 18px 18px 12px;
  }
  
  .detail-item {
    font-size: 14px;
  }
  
  .delete-btn {
    padding: 4px 10px;
    font-size: 11px;
    height: 28px;
  }
  
  .pagination-info {
    font-size: 12px;
  }
  
  .card-header {
    padding: 15px 18px;
  }
}
</style>
